#include <ds/mutex.h>
#include <stdatomic.h>
#include <process.h>
#include <sys/unistd.h>

void mutex_init(mutex_t* mutex) {
    sem_init(&mutex->sem, 1);
    mutex->owner = NULL;
}

void mutex_lock(mutex_t* mutex) {
    while (!atomic_load(&mutex->sem.count)) {
        if (mutex->owner == cur_proc) {
            break;
        }
        yield();
    }
    atomic_fetch_sub(&mutex->sem.count, 1);
    mutex->owner = cur_proc;
}

void mutex_unlock(mutex_t* mutex) {
    if (atomic_load(&mutex->sem.count) == 0) {
        mutex->owner = NULL;
    }
    sem_post(&mutex->sem);
}

int mutex_locked(mutex_t* mutex) {
    return !atomic_load(&mutex->sem.count);
}